package ccm.common;

import javax.swing.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class NativeUtils
{
    private NativeUtils()
    {

    }

    static public String getMD5(InputStream in) throws IOException, NoSuchAlgorithmException
    {
        if(in==null)
        {
            throw new NullPointerException();
        }
        final MessageDigest md5Digest=MessageDigest.getInstance("MD5");
        byte[] byteArray=new byte[1024];
        int bytesCount=0;
        while((bytesCount=in.read(byteArray))!=-1)
        {
            md5Digest.update(byteArray,0,bytesCount);
        }
        in.close();
        byte[] bytes=md5Digest.digest();
        StringBuilder sb=new StringBuilder();
        for(byte aByte: bytes)
        {
            sb.append(Integer.toString((aByte&0xff)+0x100,16).substring(1));
        }
        return sb.toString();
    }

    public static boolean isLinux()
    {
        return System.getProperty("os.name").toLowerCase().contains("linux");
    }

    public static boolean isWindows()
    {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }

    private static void load(String libname)
    {
        try
        {
            System.loadLibrary(libname);
        }catch(UnsatisfiedLinkError ex)
        {
            final String ext=NativeUtils.isLinux()?".so":".dll";
            try
            {
                final String md5=NativeUtils.getMD5(NativeUtils.class.getResourceAsStream("/lib/jni/"+libname+ext));
                final File dll=new File(System.getProperty("java.io.tmpdir")+File.separator+"ccm_jni_"+libname+"."+md5+ext);
                if(!dll.exists())
                {
                    try(InputStream in=NativeUtils.class.getResourceAsStream("/lib/jni/"+libname+ext);FileOutputStream out=new FileOutputStream(dll))
                    {
                        byte[] buf=new byte[1024];
                        int i;
                        while((i=in.read(buf))!=-1)
                        {
                            out.write(buf,0,i);
                        }
                    }
                }
                System.load(dll.getAbsolutePath());
                dll.deleteOnExit();
            }catch(Exception e)
            {
                throw new UnsatisfiedLinkError(e.getMessage()+"\n"+ex.getMessage());
            }
        }
    }

    public static void loadLibrary(String libname)
    {
        try
        {
            load(libname);
        }catch(Error ex)
        {
            JOptionPane.showMessageDialog(null,"<html><body><p style='width: 400px;'>"+ex.getMessage().replace("\n","<br>")+"</p></body></html>","错误",JOptionPane.ERROR_MESSAGE);
            throw new UnsatisfiedLinkError(ex.getMessage());
        }
    }
}